perm filename DISP.FAI[AL,HE] blob sn#660012 filedate 1982-09-27 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00009 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	TITLE Display routines to do i/o from Pascal
C00003 00003	Misc routines: BEEP, INITSC, REINIT, RESETS, CLEARS & ECHO, ESCINI & ESCINT
C00008 00004	Cursor postioning routine: SHOWCU
C00012 00005	Aux routines to set up position commands: DMPOS & DDPOS
C00014 00006	Line output routine: OUTLIN
C00020 00007	Character routines: GETCHAR, ANYCHAR & OUTCHAR
C00022 00008	Special DM routines: INSCHA, DELCHA, INSLIN & DELLIN
C00025 00009	Line editor routines: LINEDP & LOADED
C00028 ENDMK
C⊗;
TITLE Display routines to do i/o from Pascal

P ← 17
DMFLAG ←  32000
DDFLAG ←  200000
DMQUOT ←  100000
USERGO ←  2000

DD ← 20000	;RUNNING ON DATA DISK (BITS FROM GETLIN)
DM ← 40000	;  "     "  DATAMEDIA

DEFINE CW(C1,D1,C2,D2,C3,D3)<BYTE(8)D1,D2,D3(3)C1,C2,C3,4>

	TWOSEG 400000		;Initialize for two-segments
	RELOC 0
	RELOC 400000

INTERNAL BEEP,INITSC,REINIT,RESETS,CLEARS,ECHO,SHOWCU,OUTLIN,LINEDP,LOADED
INTERNAL GETCHA,ANYCHA,OUTCHA,INSCHA,DELCHA,INSLIN,DELLIN,ESCINI

;Misc routines: BEEP, INITSC, REINIT, RESETS, CLEARS & ECHO, ESCINI & ESCINT

BEEP:	HRROI 1,-1
	BEEP 1,
	POPJ P,

INITSC:	MOVEM 2,TBASE		;Remember base address of listing array
	SETO 1,
	GETLIN 1		;get our terminals characteristics
	SETZ 2,			;Assume DM
	TLNE 1,DD		;Check if Data Disk
	JRST IDD		; yup - deal with it below
	MOVE 1,[XWD DMFLAG,LPOS]
	MOVEM 1,LBCMD		;Set things up for OUTLIN
	MOVEI 4,=22		;DM's have 24 lines, but leave 2 for the wholine
	JRST I1
IDD:	AOJ 2,			; Is DD
	MOVE 1,[XWD DDFLAG,LBCMD1]
	MOVEM 1,LBCMD		;Set things up for OUTLIN
	MOVEI 4,=38		;DD's have 40 lines, but leave 2 for the wholine
I1:	MOVEM 2,TERM		;Store away for later
	MOVEM 4,1(P)		;Return screen height
	POPJ P,

	RELOC		;use low seg
TBASE:	0
TERM:	0		;0 = DM, 1 = DD
	RELOC		;back to high seg

REINIT:	PUSHJ P,CLEARS		;Clear the screen
	DPYSIZ 3002		; = 3 glitches/ 2 lines each (not really used)
	DPYPOS -1777		;Move page printer off page
	SETACT [0,,ACTTAB]	;Activate on ANY character (bye-bye line editor)
	MOVE 1,[-1,,ACTON]	;Turn on special activation mode
	TTYSET 1,
	POPJ P,

RESETS:	SETACT [0,,ACTOLD]	;Restore world for line editor
	MOVE 1,[-2,,ACTOFF]	;Turn off special activation mode & do a break N
	TTYSET 1,
	POPJ P,

ACTOFF:	XWD 002000,100		;Turn off special activation mode
	XWD 004000,516		;Clear & Normalize screen via Break N
ACTON:	XWD 001000,100		;Turn on special activation mode
ACTTAB:	XWD 777777,777777	;Special activation table
	XWD 777777,777777	; activate on ALL characters
	XWD 777777,777777
	XWD 777777,640066	;also set SUPCT,ALLACT,BSACT,SUPSCM & SUPCCR
ACTOLD:	OCT 0,0,0,0		;so we can turn off the above bits

CLEARS:	MOVE 7,TERM
	DPYOUT @CLR(7)	;Clear the screen
	POPJ P,

CLR:	DMCLRH
	DDCLRH

DDCLRH:	DDCLR
	2
	0
	0

DDCLR:	CW 1,17,2,0,1,46
	0					;Halt

DMCLRH:	XWD DMFLAG,DMCLR
	1
	0
	0

DMCLR:	77474		;clear

ECHO:	MOVEI 1,4	;Assume we want echoing on (DON = 4)
	SKIPN 2		;See what we're to do
	SOJ 1,		;If ac2 = 0 (false) turn echoing off (DOFF = 3)
	SETZM 0		;Use our terminal
	PTJOBX 0	;Do it
	POPJ P,

JOBINT ← 71

ESCINI:	MOVEM 2,ESCFLG	;Get address of flag word;
	HRRZI 1,ESCVEC	;Use ESCVEC instead of JOBCNI, JOBTPC & JOBAPR
	MOVEM 1,JOBINT	;So Pascal can use old style interrupts
	HRLZI 1,4	;Escape-I interrupt bit
	INTENB 1,	;Enable interrupts for it
	POPJ P,

ESCINT:	SETOM @ESCFLG	;Set flag when we get an escape-I interrupt
	DISMIS		;That's all we need to do

	RELOC		;Use low seg

ESCVEC:	0		;JOBCNI
	0		;JOBTPC
	ESCINT		;JOBAPR

ESCFLG:	0

	RELOC		;back to high seg

;Cursor postioning routine: SHOWCU

SHOWCU:	CAIG 3,=80	;check for line overflow
	JRST .+3	; no
	SUBI 3,=80	; yes - correct column number
	AOJ 2,		;  & bump line number
	SOJ 3,		;columns go from 0 not 1
	ADDI 2,2	;line 0 is really at line 2, so wholine isn't clobbered
	SKIPE TERM	;What sort of terminal are we using
	JRST SHDDCU	; Handle DD's below
SHDMCU:	HRRM 2,CURADR	;line	DM
	HRLM 3,CURADR	;column
	CURSOR CURADR
	POPJ P,

	RELOC		;low seg
CURADR:	0
	RELOC		;back to high seg

				;Most of this is stolen from E/363P
SHDDCU:	MOVE 5,[CW 3,0,4,0,5,0]	;Column number and line address (high & low parts)
	IMULI 2,=12		;Convert to scan line number
	ADDI 2,=10		;Put our cursor near bottom of text line
	DPB 2,[POINT 4,5,23]	;Put in low order line address
	LSH 2,-4
	DPB 2,[POINT 5,5,15]	;And high order line address
	MOVE 2,3		;Column number
	IMULI 2,6		;Column times char width in bits gives bit position
	LDB 3,[POINT 3,2,35]	;Get bit offset within graphic column
	LSH 2,-3		;Get graphic column number in low-order bits
	ADDI 2,1		;First graphics column under normal text is 1
	DPB 2,[POINT 6,5,7]	;Insert column in cmd word
	MOVEM 5,NEWCUR		;Store away new cursor position
	MOVN 3,3
	MOVSI 1,770000		;Bits for cursor
	LSH 1,-1(3)		;Adjust bits into right position within column
	TRZ 1,17		;Make sure no stray bits on
	IORI 1,2		;Make this a graphics word
	MOVEM 1,CURBTS
	DPYOUT CURHD		;Do it
	MOVEM 5,OLDCUR		;So we can erase it next time
	POPJ P,

CURHD:	CURCMD
	10
	0
	0

	RELOC		;low seg
CURCMD: CW 1,7,1,7,1,7		;Graphics mode to diddle cursors
OLDCUR:	CW 3,1,4,0,5,10		;Position cmd for old cursor
	2			;Graphic bits to erase old cursor
	CW 0,0,3,1,3,1		;Now an execute to erase the bits
NEWCUR:	CW 3,1,4,0,5,10		;Position cmd for new cursor
CURBTS:	2			;Graphic bits to draw new cursor
	CW 0,0,3,1,3,1		;Now an execute to write the bits
	0			;and finally a halt
	RELOC		;back to high seg

;Aux routines to set up position commands: DMPOS & DDPOS

DMPOS:	HRRZI 1,37614		; '177 & '14 = set cursor position
	LSH 1,7
	CAIG 3,=80		;check for line overflow
	JRST .+3		; no
	SUBI 3,=80		; yes - correct column number
	AOJ 2,			;  & bump line number
	SOJ 3,			;DM columns go from 0 not 1
	IOR 1,3			;Grab column value
	XORI 1,140
	LSH 1,7
	ADDI 2,2		;line 0 -> line 2, so wholine isn't clobbered
	IOR 1,2			;Grab line number
	XORI 1,140
	LSH 1,1
	POPJ P,

DDPOS:	CAIG 3,=80		;check for line overflow
	JRST .+3		; no
	SUBI 3,=80		; yes - correct column number
	AOJ 2,			;  & bump line number
	ADDI 2,2		;line 0 -> line 2, so wholine isn't clobbered
	IMULI 2,14		;Compute DD line number from screen text line number
	DPB 2,[400400,,2]	; (this code is snarfed from e/171p)
	TRZ 2,17
	ROT 2,20
	TDO 2,[CW 3,0,4,0,5,0]
	AOJ 3,			;DD columns start at 2
	LSH 3,=28		;Shift it to proper byte
	IOR 2,3			;Or it into command word
	MOVEM 2,LPOS		;Set up line address command
	POPJ P,

;Line output routine: OUTLIN

OUTLIN:	CAIG 5,0		;Make sure # chars to print > 0
	POPJ P,			; else nothing to do
	MOVE 6,5		;Compute col + length ( + 1)
	ADD 6,3
	CAILE 6,=81		;Make sure line won't be too long
	PUSHJ P,OUTLNG		; handle long lines below
	SKIPE TERM		;What sort of terminal are we using
	JRST ODDLIN		; Handle DD's below
ODMLIN:	PUSHJ P,DMPOS		;Set up DM cursor address
	MOVEM 1,LPOS		;Set up line address
	MOVE 6,4		;Get offset of first char to write
;	SOJ 6,			;Convert bytes to word offset
	IDIVI 6,5		; (ac7 = byte offset in first word)
	MOVE 10,TBASE		;Array base address
	ADD 10,6		;base + offset
	MOVSS 10		;Put it in left half of AC
	HRRI 10,LBUF		;DM buffer goes in right half
	MOVE 1,5		;Get # of chars to write
	ADD 1,7			;Plus any leading chars in first word
	IDIVI 1,5		;Convert to words (ac2 = # extra bytes)
	CAIE 2,0		;If any extra bytes
	AOJ 1,			; need to bump # of words to transfer	
	BLT 10,LBUF-1(1)	;Transfer line into buffer
	MOVE 10,BMASK(7)	;Get bit mask
	ANDM 10,LBUF		;Zero out extraneous leading chars
	MOVE 10,BMASK(2)	;Now handle trailing chars
	CAIE 2,0		; (if any)
	ANDCAM 10,LBUF-1(1)	;Zero out extraneous trailing chars
	HRLZI 10,774560		; 177 & 27 = erase til end of line
	MOVEM 10,LBUF(1)
	ADDI 1,2		;Number of words to send DM
	MOVEM 1,LBSIZ
	DPYOUT LBCMD		;Do it!
	POPJ P,

ODDLIN:	PUSHJ P,DDPOS		;Set up DD position command
	MOVE 6,4		;Get offset of first char to write
;	SOJ 6,			;Convert bytes to word offset
	IDIVI 6,5		; (ac7 = byte offset in first word)
	MOVE 10,TBASE		;Array base address
	ADD 10,6		;base + offset
	HRRZI 11,LBUF		;DD buffer goes in LBUF
	MOVE 1,5		;Get # of chars to write
	ADD 1,7			;Plus any leading chars in first word
	IDIVI 1,5		;Convert to words (ac2 = # extra bytes)
	CAIE 2,0		;If any extra bytes
	AOJ 1,			; need to bump # of words to transfer	
	MOVN 5,1
	HRL 10,5		;ac7 = -N,,TBASE+offset
LPLP:	MOVE 3,(10)		;Get next word to transfer
	TRO 3,1			;Make it a text word
	MOVEM 3,(11)		;Transfer it into the buffer
	AOJ 11,
	AOBJN 10,LPLP		;Get all of them
	MOVE 10,BMASK(7)	;Get bit mask
	TRO 10,1
	ANDM 10,LBUF		;Zero out extraneous leading chars
	MOVE 10,BMASK(2)	;Now handle trailing chars
	CAIE 2,0		; (if any)
	ANDCAM 10,LBUF-1(1)	;Zero out extraneous trailing chars
	MOVE 0,[CW 0,0,4,0,4,0]
	MOVEM 0,LBUF(1)		;Append an execute command
	SETZM LBUF+1(1)		;Append a halt command
	ADDI 1,4		;Number of words to send DD
	MOVEM 1,LBSIZ
	DPYOUT LBCMD		;Do it!
	POPJ P,

BMASK:	BYTE (7) 177,177,177,177,177	;Masks to zero leading chars
	BYTE (7) 0,177,177,177,177	;Use complement for killing trailing chars
	BYTE (7) 0,0,177,177,177
	BYTE (7) 0,0,0,177,177
	BYTE (7) 0,0,0,0,177

	RELOC		;use low seg
LBCMD:	XWD DDFLAG,LBCMD1
LBSIZ:	10		;# of words to write out
	0
	LPOS		;address of low order line command

LBCMD1:	CW 1,46,1,46,1,46
LPOS:	0		;Cursor command for start of line
LBUF:	BLOCK =20
	RELOC		;back to high seg

OUTLNG:	CAILE 3,=80	;Don't bother if col > 80
	POPJ P,		; just return
	PUSH P,2	;Save line number
	SUBI 6,=81	;# of chars for overflow line
	PUSH P,6	;Save it
	SUB 5,6		;# of chars for first line
	MOVE 6,4	;Offset of 1st char for 1st line
	ADD 6,5		;Offset of 1st char for 2nd line
	PUSH P,6	; save it
	PUSHJ P,OUTLIN	;Write out 1st line
	POP P,4		;Offset of 1st char
	POP P,5		;# of chars
	POP P,2		;Line number
	AOJ 2,		; bump it
	MOVEI 3,1	;Start 2nd line in 1st column
	POPJ P,		;Finally return for last part of line

;Character routines: GETCHAR, ANYCHAR & OUTCHAR

GETCHA:	INCHRW 1		;Read in the next character
	TRZ 1,400		;We never want to see meta!
	MOVEM 1,1(P)		;Return char
	POPJ P,

ANYCHA:	SETOM 1			;Assume there's a character to read in
	INCHRS (2)		;Read in the next character (if any)
	SETZM 1			;FALSE if nothing to read yet
	MOVEM 1,1(P)		;Report success or failure
	POPJ P,

OUTCHA:	LSH 4,=29		;Left justify char to output
	SKIPE TERM		;What sort of terminal are we using
	JRST OUTCDD		; Handle DD's below
OUTCDM:	PUSHJ P,DMPOS		;Set up DM position command
	MOVEM 1,LPOS		;Set up line address
	JUMPE 5,ODM1		;Skip ahead if not bold
	HRRI 4,37616		; 177 & 16 = bold on
	ROT 4,-=14		;Put bold cmd in high bits
ODM1:	MOVEM 4,LBUF		;Stick char to write in buffer
	MOVEI 1,2		;Number of words to send DM
	MOVEM 1,LBSIZ
	DPYOUT LBCMD		;Do it!
	POPJ P,

OUTCDD:	PUSHJ P,DDPOS		;Set up DD position command
	TRO 4,1			;Make it a text word
	MOVEM 4,LBUF		;Transfer it into the buffer
	MOVE 1,[CW 0,0,4,0,4,0]
	MOVEM 1,LBUF+1		;Append an execute command
	SETZM LBUF+2		;Append a halt command
	MOVEI 1,5		;Number of words to send DD
	MOVEM 1,LBSIZ
	DPYOUT LBCMD		;Do it!
	POPJ P,

;Special DM routines: INSCHA, DELCHA, INSLIN & DELLIN

INSCHA:	PUSHJ P,DMPOS		;Set up DM position command
	LSH 1,7			;Flush 177 byte
	MOVEM 1,IDPOS		;Set up line address
	MOVE 1,[BYTE (7) 20,34,30,16,0]	;Enter i/d mode, add space, can, bold
	MOVEM 1,IDPOS+1		;Set up I/D command
	LSH 4,=29		;Left shift char to output
	MOVEM 4,IDPOS+2		;Stick it into buffer
	MOVEI 1,3
	MOVEM 1,IDCMD+1		;Three words to write out
	DPYOUT IDCMD		;Do it!
	POPJ P,

DELCHA:	PUSHJ P,DMPOS		;Set up DM position command
	LSH 1,7			;Flush 177 byte
	MOVEM 1,IDPOS		;Set up line address
	MOVE 1,[BYTE (7) 20,10,30,16,0]	;Enter i/d mode, delete char, can, bold
	MOVEM 1,IDPOS+1		;Set up I/D command
	MOVEI 1,2
	MOVEM 1,IDCMD+1		;Two words to write out
	DPYOUT IDCMD		;Do it!
	POPJ P,

INSLIN:	MOVEI 4,12		;12 = Add row in i/d mode
	CAIA			;Skip ahead to common code
DELLIN:	MOVEI 4,32		;32 = Delete row in i/d mode
	SKIPN 5,3		;Save # of lines to insert/delete
	POPJ P,			; (if none all done)
	MOVEI 3,1
	PUSHJ P,DMPOS		;Set up positioning command;
	LSH 1,7			;Flush 177 byte
	IORI 1,40		;Or enter i/d mode (= 20) into command
	MOVEM 1,IDPOS		;Set up line address & enter i/d mode
	MOVE 1,[POINT 7,IDPOS+1] ;Byte pointer for where to put i/d chars
IDLP:	IDPB 4,1		;Move it into buffer
	SOJG 5,IDLP		;# of lines to do
	MOVEI 4,30		;Exit i/d mode
	IDPB 4,1
	IDPB 5,1		;Tack on some nulls to fill word
	IDPB 5,1
	IDPB 5,1
	IDPB 5,1
	IBP 1
	HRRZ 2,1		;Ac2 = end of command buffer
	SUBI 2,IDPOS		;Get # of chars to write out
	MOVEM 2,IDCMD+1
	DPYOUT IDCMD		;Do it!
	POPJ P,

	RELOC		;use low seg
IDCMD:	XWD DMQUOT+DDFLAG+USERGO,IDPOS
	3		;# of words to write out
	0
	0

IDPOS:	0		;Cursor command for start of line
	BYTE (7) 20,34,30,16,0	;Enter i/d mode, add space, can, bold
	0		;Char to output
	0
	0
	0
	RELOC		;back to high seg

;Line editor routines: LINEDP & LOADED

LINEDP:	ADDI 2,2	;line 0 is really at line 2, so wholine isn't clobbered
	AOJ 2,			;we use the same algorithm as E (/171p)
	LSH 2,7			;multiply by 200
	MOVE 3,[-3]		;For DM's
	SKIPE TERM		;Different spacing for different terminal types
	MOVE 3,[-5]		;For DD's
	IDIV 2,3
	ADDI 2,1000		;top of screen = 1000
	LEYPOS (2)		;Do it
	POPJ P,

LOADED:	MOVEI 1,0		;Load line editor & move cursor to char #N
	SOJLE 5,LOED0		; (actually <cntl><n-1><cntl><space>)
	IDIVI 5,=10
	MOVE 1,[BYTE (9) 260,260,240,0]	;<cntl>0 <cntl>0 <cntl><sp> null
	LSH 5,=27
	ADD 1,5			;Deal with 10's
	LSH 6,=18
	ADD 1,6			;Deal with 1's
LOED0:	MOVEM 1,LOED3		;Number of spaces into line to move cursor
	MOVE 10,[POINT 7,LBUF]	;Byte pointer for where to put line
	JUMPE 4,LOED1		;Skip ahead if no chars to load
	MOVE 6,3		;Get offset of first char to load in
;	SOJ 6,			;Convert bytes to word offset
	IDIVI 6,5		; (ac7 = byte offset in first word)
	ADD 6,TBASE		;base + offset
	IMUL 7,[-7]
	ADDI 7,=36		;Make up P field
	LSH 7,=30
	XOR 7,[POINT 7,(6),35]	;Need to make up byte pointer
LOEDLP:	ILDB 1,7		;Get next char
	IDPB 1,10		;Move it into buffer
	SOJG 4,LOEDLP		;Get them all
LOED1:	HRRZI 1,15		;Tack on a CR
	IDPB 1,10		;Move it into buffer
	PUSHJ P,LINEDP		;Move line editor to right line
	PTL7W9 LOED2		; & load it
	POPJ P,

LOED2:	0			;Use own terminal
	LBUF			;address of string to load
	LOED3			;9 bit string of simulated type ahead

	RELOC			;Back to low seg
LOED3:	BYTE (9) 260,260,240,0	;<cntl>0 <cntl>0 <cntl><sp>
	RELOC			;To high seg

END